package cn.janescott.inner.space.shiro.realm;

import cn.janescott.inner.space.shiro.token.UsernamePasswordCodeToken;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * 1、
 * Shiro + Redis 的集成，也提供Ehcache的依赖Jar。------- 实现CacheManager
 * Shiro 初始权限动态加载。 ---------------------------- ?
 * Shiro 自定义权限校验Filter定义，及功能实现。 ----------
 * Shiro Ajax请求权限不满足，拦截后解决方案。------------- AOP
 * 2、
 * Shiro JSP标签使用。
 * Shiro 登录后跳转到最后一个访问的页面。 ---------------- 带路径登录
 * 用户禁止登录。 -------------------------------------- 用户状态表
 * 在线显示，在线用户管理（踢出登录）。 ------------------ 缓存中记录在线人数  清除缓存中登录信息 == 剔除登录
 * 登录注册密码加密传输。 ------------------------------- 公密  & 私密
 * 密码修改。 ------------------------------------------
 * 用户个人中心。
 * 权限的增删改查。
 * 角色的增删改查。
 * 权限->角色->用户之间的关系维护。
 * 管理员权限的自动添加（当有一个权限创建，自动添加到管理员角色下，保证管理员是最大权限）。
 * Spring定时任务数据化数据。
 * 集成多种验证码
 * 一个帐号多处登录限制，踢出用户。 ---------------------- 缓存踢出
 *
 * @author scott
 * @date 2018/7/26
 */
public class DatabaseShiroRealm extends AuthorizingRealm {

    private RealmHandler realmHandler;

    public DatabaseShiroRealm setRealmHandler(RealmHandler realmHandler) {
        this.realmHandler = realmHandler;
        return this;
    }

    /**
     * 设置密码匹配器
     *
     * @param credentialsMatcher 密码匹配器 默认{@link org.apache.shiro.authc.credential.SimpleCredentialsMatcher}
     */
    public DatabaseShiroRealm setPasswordMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
        return this;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        if (token instanceof UsernamePasswordCodeToken) {
            UsernamePasswordCodeToken usernamePasswordToken = (UsernamePasswordCodeToken) token;

            //1、获取用户信息
            UsernamePasswordCodeToken dbToken = (UsernamePasswordCodeToken) realmHandler.getToken(usernamePasswordToken.getUsername());

            //2、如果为空，则表示用户不存在
            if (null == dbToken) {
                throw new UnknownAccountException("用户名不存在！");
            }

//            if () {
//
//            }
            //3、如果不为空
            return new SimpleAuthenticationInfo(dbToken, dbToken.getPassword(), getName());
        }
        return null;
    }

    /**
     * Shiro + Mysql + Redis 的集成，提供数据库和缓存登录和授权
     * Shiro 权限修改需要动态更新用户权限
     * Shiro 权限校验Filter，对不同的资源进行不同的验证方案，如公共资源、私有资源
     * Shiro Ajax请求权限不满足，拦截后解决方案。
     * Shiro 登录后跳转到最后一个访问的页面。
     * 管理员设置普通用户禁止登录(设置禁止登录时长)。
     * 管理员锁定其他用户
     * 在线显示，在线用户管理（踢出登录）。
     * 登录注册密码加密传输。
     * 密码修改。
     * 用户个人中心。
     * 权限的增删改查。
     * 角色的增删改查。
     * 权限->角色->用户之间的关系维护。
     * 管理员权限的自动添加（当有一个权限创建，自动添加到管理员角色下，保证管理员是最大权限）。
     * 集成多种验证方式(暂时先实现一种——验证码)
     * 一个帐号多处登录限制，踢出用户。
     */
}
